﻿using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace ICodeShare.UI.Controls.Primitives
{
    /// <summary>
    /// 扩展Toggle命令绑定
    /// </summary>
    public abstract class ToggleButtonBase : ToggleButton
    {
        #region Members

        /// <summary>
        /// An event that is raised when the value of IsChecked changes.
        /// </summary>
        public event EventHandler CheckedChanged;

        #endregion Members

        #region Constructors

        static ToggleButtonBase()
        {
            IsCheckedProperty.OverrideMetadata(typeof(ToggleButtonBase), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCheckedChanged));
        }

        public ToggleButtonBase()
        {
            Checked += ToggleButtonBase_Checked;
            Unchecked += ToggleButtonBase_Unchecked;
        }

        #endregion Constructors

        #region Properties

        #region IsChecked 是否选中

        private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var switchButton = (ToggleButtonBase)d;
            if (switchButton != null)
            {
                var oldValue = (bool?)e.OldValue;
                var newValue = (bool?)e.NewValue;

                if (oldValue != newValue)
                {
                    var command = switchButton.CheckChangedCommand;
                    var commandParameter = switchButton.CheckChangedCommandParameter ?? switchButton;
                    if (command != null && command.CanExecute(commandParameter))
                    {
                        command.Execute(commandParameter);
                    }

                    var eh = switchButton.CheckedChanged;
                    if (eh != null)
                    {
                        eh(switchButton, EventArgs.Empty);
                    }
                }
            }
        }

        #endregion IsChecked 是否选中

        #region ICommand 路由命令

        #region CheckChangedCommand 选中状态变更命令

        /// <summary>
        /// Gets/sets the command which will be executed if the IsChecked property was changed.
        /// </summary>
        public ICommand CheckChangedCommand
        {
            get { return (ICommand)GetValue(CheckChangedCommandProperty); }
            set { SetValue(CheckChangedCommandProperty, value); }
        }

        public static readonly DependencyProperty CheckChangedCommandProperty =
            DependencyProperty.Register("CheckChangedCommand", typeof(ICommand), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion CheckChangedCommand 选中状态变更命令

        #region CheckChangedCommandParameter

        /// <summary>
        /// Gets/sets the command parameter which will be passed by the CheckChangedCommand.
        /// </summary>
        public object CheckChangedCommandParameter
        {
            get { return (object)GetValue(CheckChangedCommandParameterProperty); }
            set { SetValue(CheckChangedCommandParameterProperty, value); }
        }

        public static readonly DependencyProperty CheckChangedCommandParameterProperty =
            DependencyProperty.Register("CheckChangedCommandParameter", typeof(object), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion CheckChangedCommandParameter

        #region CheckedCommand

        /// <summary>
        /// Gets/sets the command which will be executed if the checked event of the control is fired.
        /// </summary>
        public ICommand CheckedCommand
        {
            get { return (ICommand)GetValue(CheckedCommandProperty); }
            set { SetValue(CheckedCommandProperty, value); }
        }

        public static readonly DependencyProperty CheckedCommandProperty =
            DependencyProperty.Register("CheckedCommand", typeof(ICommand), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion CheckedCommand

        #region CheckedCommandParameter

        /// <summary>
        /// Gets/sets the command parameter which will be passed by the UnCheckedCommand.
        /// </summary>
        public object UnCheckedCommandParameter
        {
            get { return (object)GetValue(UnCheckedCommandParameterProperty); }
            set { SetValue(UnCheckedCommandParameterProperty, value); }
        }

        /// <summary>
        /// Gets/sets the command parameter which will be passed by the CheckedCommand.
        /// </summary>
        public object CheckedCommandParameter
        {
            get { return (object)GetValue(CheckedCommandParameterProperty); }
            set { SetValue(CheckedCommandParameterProperty, value); }
        }

        public static readonly DependencyProperty CheckedCommandParameterProperty =
            DependencyProperty.Register("CheckedCommandParameter", typeof(object), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion CheckedCommandParameter

        #region UnCheckedCommand

        /// <summary>
        /// Gets/sets the command which will be executed if the checked event of the control is fired.
        /// </summary>
        public ICommand UnCheckedCommand
        {
            get { return (ICommand)GetValue(UnCheckedCommandProperty); }
            set { SetValue(UnCheckedCommandProperty, value); }
        }

        public static readonly DependencyProperty UnCheckedCommandProperty =
            DependencyProperty.Register("UnCheckedCommand", typeof(ICommand), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion UnCheckedCommand

        #region UnCheckedCommandParameter

        public static readonly DependencyProperty UnCheckedCommandParameterProperty =
            DependencyProperty.Register("UnCheckedCommandParameter", typeof(object), typeof(ToggleButtonBase), new PropertyMetadata(null));

        #endregion UnCheckedCommandParameter

        #endregion ICommand 路由命令

        #endregion Properties

        #region Methods

        /// <summary>
        /// 选中事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToggleButtonBase_Checked(object sender, RoutedEventArgs e)
        {
            var command = this.CheckedCommand;
            var commandParameter = this.CheckedCommandParameter ?? this;
            if (command != null && command.CanExecute(commandParameter))
            {
                command.Execute(commandParameter);
            }
        }

        /// <summary>
        /// 未选中事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToggleButtonBase_Unchecked(object sender, RoutedEventArgs e)
        {
            var command = this.UnCheckedCommand;
            var commandParameter = this.UnCheckedCommandParameter ?? this;
            if (command != null && command.CanExecute(commandParameter))
            {
                command.Execute(commandParameter);
            }
        }

        #endregion Methods
    }
}